import Cookies from 'js-cookie'
// cookie保存的天数
import config from '@/config'
import { forEach, hasOneOf, objEqual } from '@/libs/tools'
import store from '@/store'
const { title, cookieExpires, useI18n, report_color } = config

export const TOKEN_KEY = 'token'
export const MENU_LIST = 'menus'
export const USER_NAME = 'username'
export const REPORT_DATA = 'report_data'

export const setToken = token => {
  Cookies.set(TOKEN_KEY, token, { expires: cookieExpires || 1 })
}
export const getToken = () => {
  const token = Cookies.get(TOKEN_KEY)
  if (token) return token
  else return false
}

export const setRoutes = routes => {
  Cookies.set(MENU_LIST, JSON.stringify(routes), {
    expires: cookieExpires || 1
  })
}

export const removeCookieKey = name => {
  Cookies.remove(name)
}

export const getRoutes = () => {
  if (Cookies.get(MENU_LIST)) {
    const routes = JSON.parse(Cookies.get(MENU_LIST))
    if (routes) return routes
    else return []
  } else {
    return []
  }
}

export const setUserName = name => {
  Cookies.set(USER_NAME, name, { expires: cookieExpires || 1 })
}

export const getUserName = () => {
  const name = Cookies.get(USER_NAME)
  if (name) return name
  else return false
}

export const hasChild = item => {
  return item.children && item.children.length !== 0
}

const showThisMenuEle = (item, access) => {
  if (item.meta && item.meta.access && item.meta.access.length) {
    if (hasOneOf(item.meta.access, access)) return true
    else return false
  } else return true
}
/**
 * @param {Array} list 通过路由列表得到菜单列表
 * @returns {Array}
 */
export const getMenuByRouter = (list, access) => {
  let res = []
  const menus = getRoutes()
  forEach(list, item => {
    if (
      (!item.meta || (item.meta && !item.meta.hideInMenu)) &&
      menus.includes(item.name)
    ) {
      let obj = {
        icon: (item.meta && item.meta.icon) || '',
        name: item.name,
        meta: item.meta
      }
      if (
        (hasChild(item) || (item.meta && item.meta.showAlways)) &&
        showThisMenuEle(item, access)
      ) {
        obj.children = getMenuByRouter(item.children, access)
      }
      if (item.meta && item.meta.href) obj.href = item.meta.href
      if (showThisMenuEle(item, access)) res.push(obj)
    }
  })
  return res
}

/**
 * @param {Array} routeMetched 当前路由metched
 * @returns {Array}
 */
export const getBreadCrumbList = (route, homeRoute) => {
  let homeItem = { ...homeRoute, icon: homeRoute.meta.icon }
  let routeMetched = route.matched
  if (routeMetched.some(item => item.name === homeRoute.name)) {
    return [homeItem]
  }
  let res = routeMetched
    .filter(item => {
      return item.meta === undefined || !item.meta.hideInBread
    })
    .map(item => {
      let meta = { ...item.meta }
      if (meta.title && typeof meta.title === 'function') {
        meta.__titleIsFunction__ = true
        meta.title = meta.title(route)
      }
      let obj = {
        icon: (item.meta && item.meta.icon) || '',
        name: item.name,
        meta: meta
      }
      return obj
    })
  res = res.filter(item => {
    return !item.meta.hideInMenu
  })
  return [{ ...homeItem, to: homeRoute.path }, ...res]
}

export const getRouteTitleHandled = route => {
  let router = { ...route }
  let meta = { ...route.meta }
  let title = ''
  if (meta.title) {
    if (typeof meta.title === 'function') {
      meta.__titleIsFunction__ = true
      title = meta.title(router)
    } else title = meta.title
  }
  meta.title = title
  router.meta = meta
  return router
}

export const showTitle = (item, vm) => {
  let { title, __titleIsFunction__ } = item.meta
  if (!title) return
  if (useI18n) {
    if (title.includes('{{') && title.includes('}}') && useI18n) {
      title = title.replace(/({{[\s\S]+?}})/, (m, str) =>
        str.replace(/{{([\s\S]*)}}/, (m, _) => vm.$t(_.trim()))
      )
    } else if (__titleIsFunction__) title = item.meta.title
    else title = vm.$t(item.name)
  } else title = (item.meta && item.meta.title) || item.name
  return title
}

/**
 * @description 本地存储和获取标签导航列表
 */
export const setTagNavListInLocalstorage = list => {
  localStorage.tagNaveList = JSON.stringify(list)
}
/**
 * @returns {Array} 其中的每个元素只包含路由原信息中的name, path, meta三项
 */
export const getTagNavListFromLocalstorage = () => {
  const list = localStorage.tagNaveList
  return list ? JSON.parse(list) : []
}

/**
 * @param {Array} routers 路由列表数组
 * @description 用于找到路由列表中name为home的对象
 */
export const getHomeRoute = (routers, homeName = 'home') => {
  let i = -1
  let len = routers.length
  let homeRoute = {}
  while (++i < len) {
    let item = routers[i]
    if (item.children && item.children.length) {
      let res = getHomeRoute(item.children, homeName)
      if (res.name) return res
    } else {
      if (item.name === homeName) homeRoute = item
    }
  }
  return homeRoute
}

/**
 * @param {*} list 现有标签导航列表
 * @param {*} newRoute 新添加的路由原信息对象
 * @description 如果该newRoute已经存在则不再添加
 */
export const getNewTagList = (list, newRoute) => {
  const { name, path, meta } = newRoute
  let newList = [...list]
  if (newList.findIndex(item => item.name === name) >= 0) return newList
  else newList.push({ name, path, meta })
  return newList
}

/**
 * @param {*} access 用户权限数组，如 ['super_admin', 'admin']
 * @param {*} route 路由列表
 */
const hasAccess = (access, route) => {
  if (route.meta && route.meta.access) {
    return hasOneOf(access, route.meta.access)
  } else return true
}

const isRouter = item => {
  let menus = getRoutes()
  // //console.log(menus)
  // //console.log(item.name)
  return menus.includes(item.name)
}
/**
 * 权鉴
 * @param {*} name 即将跳转的路由name
 * @param {*} access 用户权限数组
 * @param {*} routes 路由列表
 * @description 用户是否可跳转到该页
 */
export const canTurnTo = (name, access, routes) => {
  const routePermissionJudge = list => {
    return list.some(item => {
      if (item.children && item.children.length) {
        return routePermissionJudge(item.children)
      } else if (item.name === name) {
        return isRouter(item)
      }
    })
  }
  return routePermissionJudge(routes)
}

export const turnAccessRoute = (name, routes) => {
  const routePermissionJudge = list => {
    return list.some(item => {
      if (item.children && item.children.length) {
        return routePermissionJudge(item.children)
      } else if (item.name === name) {
        return isRouter(item)
      }
    })
  }

  return routePermissionJudge(routes)
}

/**
 * @param {String} url
 * @description 从URL中解析参数
 */
export const getParams = url => {
  const keyValueArr = url.split('?')[1].split('&')
  let paramObj = {}
  keyValueArr.forEach(item => {
    const keyValue = item.split('=')
    paramObj[keyValue[0]] = keyValue[1]
  })
  return paramObj
}

/**
 * @param {Array} list 标签列表
 * @param {String} name 当前关闭的标签的name
 */
export const getNextRoute = (list, route) => {
  let res = {}
  if (list.length === 2) {
    res = getHomeRoute(list)
  } else {
    const index = list.findIndex(item => routeEqual(item, route))
    if (index === list.length - 1) res = list[list.length - 2]
    else res = list[index + 1]
  }
  return res
}

/**
 * @param {Number} times 回调函数需要执行的次数
 * @param {Function} callback 回调函数
 */
export const doCustomTimes = (times, callback) => {
  let i = -1
  while (++i < times) {
    callback(i)
  }
}

/**
 * @param {Object} file 从上传组件得到的文件对象
 * @returns {Promise} resolve参数是解析后的二维数组
 * @description 从Csv文件中解析出表格，解析成二维数组
 */
export const getArrayFromFile = file => {
  let nameSplit = file.name.split('.')
  let format = nameSplit[nameSplit.length - 1]
  return new Promise((resolve, reject) => {
    let reader = new FileReader()
    reader.readAsText(file) // 以文本格式读取
    let arr = []
    reader.onload = function (evt) {
      let data = evt.target.result // 读到的数据
      let pasteData = data.trim()
      arr = pasteData
        .split(/[\n\u0085\u2028\u2029]|\r\n?/g)
        .map(row => {
          return row.split('\t')
        })
        .map(item => {
          return item[0].split(',')
        })
      if (format === 'csv') resolve(arr)
      else reject(new Error('[Format Error]:你上传的不是Csv文件'))
    }
  })
}

/**
 * @param {Array} array 表格数据二维数组
 * @returns {Object} { columns, tableData }
 * @description 从二维数组中获取表头和表格数据，将第一行作为表头，用于在iView的表格中展示数据
 */
export const getTableDataFromArray = array => {
  let columns = []
  let tableData = []
  if (array.length > 1) {
    let titles = array.shift()
    columns = titles.map(item => {
      return {
        title: item,
        key: item
      }
    })
    tableData = array.map(item => {
      let res = {}
      item.forEach((col, i) => {
        res[titles[i]] = col
      })
      return res
    })
  }
  return {
    columns,
    tableData
  }
}

export const findNodeUpper = (ele, tag) => {
  if (ele.parentNode) {
    if (ele.parentNode.tagName === tag.toUpperCase()) {
      return ele.parentNode
    } else {
      return findNodeUpper(ele.parentNode, tag)
    }
  }
}

export const findNodeUpperByClasses = (ele, classes) => {
  let parentNode = ele.parentNode
  if (parentNode) {
    let classList = parentNode.classList
    if (
      classList &&
      classes.every(className => classList.contains(className))
    ) {
      return parentNode
    } else {
      return findNodeUpperByClasses(parentNode, classes)
    }
  }
}

export const findNodeDownward = (ele, tag) => {
  const tagName = tag.toUpperCase()
  if (ele.childNodes.length) {
    let i = -1
    let len = ele.childNodes.length
    while (++i < len) {
      let child = ele.childNodes[i]
      if (child.tagName === tagName) return child
      else return findNodeDownward(child, tag)
    }
  }
}

export const showByAccess = (access, canViewAccess) => {
  return hasOneOf(canViewAccess, access)
}

/**
 * @description 根据name/params/query判断两个路由对象是否相等
 * @param {*} route1 路由对象
 * @param {*} route2 路由对象
 */
export const routeEqual = (route1, route2) => {
  const params1 = route1.params || {}
  const params2 = route2.params || {}
  const query1 = route1.query || {}
  const query2 = route2.query || {}
  return (
    route1.name === route2.name &&
    objEqual(params1, params2) &&
    objEqual(query1, query2)
  )
}

/**
 * 判断打开的标签列表里是否已存在这个新添加的路由对象
 */
export const routeHasExist = (tagNavList, routeItem) => {
  let len = tagNavList.length
  let res = false
  doCustomTimes(len, index => {
    if (routeEqual(tagNavList[index], routeItem)) res = true
  })
  return res
}

export const localSave = (key, value) => {
  localStorage.setItem(key, value)
}

export const localRead = key => {
  return localStorage.getItem(key) || ''
}

// scrollTop animation
export const scrollTop = (el, from = 0, to, duration = 500, endCallback) => {
  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame =
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function (callback) {
        return window.setTimeout(callback, 1000 / 60)
      }
  }
  const difference = Math.abs(from - to)
  const step = Math.ceil((difference / duration) * 50)

  const scroll = (start, end, step) => {
    if (start === end) {
      endCallback && endCallback()
      return
    }

    let d = start + step > end ? end : start + step
    if (start > end) {
      d = start - step < end ? end : start - step
    }

    if (el === window) {
      window.scrollTo(d, d)
    } else {
      el.scrollTop = d
    }
    window.requestAnimationFrame(() => scroll(d, end, step))
  }
  scroll(from, to, step)
}

/**
 * @description 根据当前跳转的路由设置显示在浏览器标签的title
 * @param {Object} routeItem 路由对象
 * @param {Object} vm Vue实例
 */
export const setTitle = (routeItem, vm) => {
  const handledRoute = getRouteTitleHandled(routeItem)
  const pageTitle = showTitle(handledRoute, vm)
  const resTitle = pageTitle ? `${title} - ${pageTitle}` : title
  window.document.title = resTitle
}

// employreport       员工流动统计
// salereport         销售统计报表
// viewreport         面试统计信息
// vistreport         客户拜访量
// returnratereport   项目总回款率表数据
// projectsreport     项目总统计表数据
// returnreport       各项目回款率表数据
// convratereport     转化率数据
// regnumreport       注册统计数据
// passnumreport      通过数量表
// pricereport        通过金额表数据
export const dataArrayList = data => {
  let payload = {}
  if (data.data) {
    let reportArray = {}
    forEach(Object.keys(data.data), item => {
      if (data.data[item] instanceof Array) {
        switch (item) {
          case 'projectsreport':
            payload['projectsreport'] = projectReportArray(data.data[item])
            break
          case 'salereport':
            payload['salereport'] = data.data[item]
            break
          default:
            break
        }
      } else {
        switch (item) {
          case 'passnumreport': // 通过数量表
            reportArray['passnumreport'] = passnumReportArray(data.data[item])
            break
          case 'returnratereport': // 项目总回款率表数据
            reportArray['returnratereport'] = returnrateReportArray(
              data.data[item]
            )
            break
          case 'regnumreport': // 注册统计数据
            reportArray['regnumreport'] = regnumReportArray(data.data[item])
            break
          case 'pricereport': // 通过金额表数据
            reportArray['pricereport'] = priceReportArray(data.data[item])
            break
          case 'convratereport': // 转化率数据
            reportArray['convratereport'] = convrateReportArray(
              data.data[item]
            )
            break
          case 'returnreport': // 各项目回款率表数据
            reportArray['returnreport'] = returnReportArray(data.data[item])
            break
          case 'employreport':
          case 'viewreport':
          case 'vistreport':
            payload[item] = data.data[item]
            break
          default:
            break
        }
      }
      payload.reportArray = reportArray
    })
  }
  return Promise.resolve(payload)
}

function projectReportArray (data) {
  let f = [] // 拒绝数量
  let p = [] // 通过数量
  let cpa = [] // 注册数量
  let tprice = [] // 通过金额
  let req = [] // 申请数量
  let ctime = []
  forEach(data, item => {
    ctime = [...ctime, item.ctime]
    f = [...f, item.f]
    p = [...p, item.p]
    cpa = [...cpa, item.cpa]
    tprice = [...tprice, item.tprice]
    req = [...req, item.req]
  })
  return { ctime: dateOrder(ctime), f, p, cpa, tprice, req }
}

function convrateReportArray (data) {
  let proname = []
  let ctime = new Set()
  let series = []
  Object.keys(data).forEach((key, index) => {
    proname = [key, ...proname]
    let series_obj = {}
    series_obj.name = key
    series_obj.type = 'line'
    series_obj.smooth = true
    series_obj.data = []
    series_obj.itemStyle = {}
    series_obj.itemStyle.normal = {}
    series_obj.itemStyle.normal.show = true
    series_obj.itemStyle.normal.formatter = '{c} %'
    forEach(data[key], item => {
      ctime.add(item.ctime)
      series_obj.data = [...series_obj.data, parseFloat(item.conver) * 100]
    })
    series = [...series, series_obj]
  })
  const yAxis = [
    {
      type: 'value',
      name: '百分比',
      min: 0,
      axisLabel: {
        formatter: '{value} %'
      },
      splitLine: {
        show: false
      }
    }
  ]
  return {
    title: '各项目转化率统计',
    ctime: dateOrder(Array.from(ctime)),
    proname,
    series,
    yAxis
  }
}

function passnumReportArray (data) {
  let proname = []
  let ctime = new Set()
  let p = []
  let series = []
  Object.keys(data).forEach((key, index) => {
    proname = [...proname, key]
    let series_obj = {}
    series_obj.name = key
    series_obj.type = 'line'
    series_obj.smooth = true
    series_obj.data = []
    forEach(data[key], item => {
      ctime.add(item.ctime)
      series_obj.data = [...series_obj.data, item.p]
    })
    series = [...series, series_obj]
  })
  return {
    title: '项目数量通过对比',
    ctime: dateOrder(Array.from(ctime)),
    proname,
    series
  }
}

function regnumReportArray (data) {
  let proname = []
  let ctime = new Set()
  let series = []
  Object.keys(data).forEach((key, index) => {
    proname = [...proname, key]
    let series_obj = {}
    series_obj.name = key
    series_obj.type = 'line'
    series_obj.smooth = true
    series_obj.data = []
    forEach(data[key], item => {
      ctime.add(item.ctime)
      series_obj.data = [...series_obj.data, item.cpa]
    })
    series = [...series, series_obj]
  })
  return {
    title: '项目注册量对比',
    ctime: dateOrder(Array.from(ctime)),
    proname,
    series
  }
}

function priceReportArray (data) {
  let proname = []
  let ctime = new Set()
  let series = []
  Object.keys(data).forEach((key, index) => {
    proname = [...proname, key]
    let series_obj = {}
    series_obj.name = key
    series_obj.data = []
    if (key === '总计') {
      series_obj.type = 'line'
      series_obj.smooth = true
    } else {
      series_obj.type = 'bar'
      series_obj.barWidth = '50'
    }

    forEach(data[key], item => {
      ctime.add(item.ctime)
      series_obj.data = [...series_obj.data, item.tprice]
    })
    series = [...series, series_obj]
  })
  const yAxis = [
    {
      type: 'value',
      name: '金额',
      min: 0,
      interval: 50000,
      axisLabel: {
        formatter: '{value} 元'
      },
      splitLine: {
        show: false
      }
    }
  ]
  return {
    title: '各项目通过金额统计',
    ctime: dateOrder(Array.from(ctime)),
    proname,
    series,
    yAxis
  }
}

function returnrateReportArray (data) {
  let ctime = new Set()
  let yAxis_names = [
    { name: '应回款数量', key: 'yreturn' },
    { name: '回款数量', key: 'returnum' },
    { name: '回款率', key: 'rate' }
  ]
  let series = []
  let proname = []

  forEach(yAxis_names, (axis, i) => {
    proname = [...proname, axis.name]
    let series_obj = {}
    series_obj.name = axis.name
    series_obj.type = 'line'
    series_obj.data = []
    series_obj.smooth = true
    forEach(data, item => {
      ctime.add(item.ctime)
      series_obj.data = [...series_obj.data, item[axis.key]]
    })
    series = [...series, series_obj]
  })

  return {
    title: '项目总回款统计',
    ctime: dateOrder(Array.from(ctime)),
    proname,
    series
  }
}

function returnReportArray (data) {
  let proname = []
  let ctime = new Set()
  let series = []
  Object.keys(data).forEach((key, index) => {
    proname = [...proname, key]
    let series_obj = {}
    series_obj.name = key + '回款'
    series_obj.type = 'line'
    series_obj.data = []
    series_obj.smooth = true
    series_obj.itemStyle = {}
    series_obj.itemStyle.normal = {}
    series_obj.itemStyle.normal.show = true
    series_obj.itemStyle.normal.formatter = '{c} %'
    forEach(data[key], item => {
      ctime.add(item.ctime)
      series_obj.data = [...series_obj.data, parseFloat(item.rate) * 100]
    })
    series = [...series, series_obj]
  })
  const yAxis = [
    {
      type: 'value',
      name: '百分比',
      min: 0,
      axisLabel: {
        formatter: '{value} %'
      },
      splitLine: {
        show: false
      }
    }
  ]
  return {
    title: '各项目回款对比统计',
    ctime: dateOrder(Array.from(ctime)),
    proname,
    series,
    yAxis
  }
}

function dateOrder (ctime) {
  let dates
  dates = ctime.sort((a, b) => {
    return (
      new Date(a.replace(/-/g, '/')).getTime() -
      new Date(b.replace(/-/g, '/')).getTime()
    )
  })
  return dates
}
